package models

import (
	"errors"
	"gitee.com/sansaniot/ssiot-core/httpmvc/model"
	cQuery "ssadmin/common/query"
	"ssadmin/common/utils"
	"ssadmin/internal/admin/models/query"
	"time"

	"gorm.io/gorm"
)

type Role struct {
	RoleId        string    `json:"id" gorm:"column:id;primaryKey;type:varchar(64);comment:角色id"`
	RoleName      string    `json:"roleName" gorm:"type:varchar(10);comment:角色名称"`
	Remark        string    `json:"remark" gorm:"type:varchar(100);comment:角色描述"`
	CreateTimeDts time.Time `json:"-" gorm:"type:datetime;column:create_time;comment:创建时间"`
	CreateTime    string    `json:"createTime" gorm:"-"`
	ModifyTimeDts time.Time `json:"-" gorm:"type:datetime;column:update_time;comment:修改时间"`
	ModifyTime    string    `json:"modifyTime" gorm:"-"`
	CreatorId     string    `json:"creatorId" gorm:"type:varchar(64);comment:CreatorId"`
	Creator       string    `json:"creator" gorm:"type:varchar(64);comment:Creator"`
	Type          string    `json:"type" gorm:"type:varchar(15);comment:Type"`
	model.Model
}

func (r *Role) FindList(q *query.RoleQuery, list *[]Role, count *int64) error {
	err := r.Orm.Model(&Role{}).Scopes(
		cQuery.MakeCondition(q.GetNeedSearch()),
		cQuery.OrderDest("create_time", true),
		cQuery.Paginate(q.GetPageSize(), q.GetPageIndex()),
	).Find(list).Limit(-1).Offset(-1).Count(count).Error

	for i, info := range *list {
		(*list)[i].CreateTime = info.CreateTimeDts.Format(utils.TIME_FMT_FULL)
		(*list)[i].ModifyTime = info.ModifyTimeDts.Format(utils.TIME_FMT_FULL)
	}

	return err
}

func (r *Role) FindRecurList(q *query.RoleQuery, list *[]Role, count *int64) error {
	sql := "select * from sys_role where creator_id in (\nWITH RECURSIVE r_user AS (\n\t" +
		"SELECT\n\t\t" +
		"sys_user.* \n\t" +
		"FROM\n\t\t" +
		"sys_user \n\t" +
		"WHERE\n\t\t" +
		"sys_user.creator_id = ? UNION ALL\n\t" +
		"SELECT\n\t\t" +
		"sys_user.* \n\t" +
		"FROM\n\t\t" +
		"sys_user,\n\t\t" +
		"r_user \n\t" +
		"WHERE\n\t\t" +
		"sys_user.creator_id = r_user.ID \n\t" +
		") SELECT\n\t" +
		"id\nFROM\n\t" +
		"r_user \n) or creator_id = ?"
	where := make([]func(db *gorm.DB) *gorm.DB, 0)

	where = append(where, cQuery.OrderDest("create_time", true))
	err := r.Orm.Model(&Role{}).Scopes(where...).Raw(sql, q.CreatorId, q.CreatorId).Scan(&list).Limit(-1).Offset(-1).Count(count).Error
	for i, info := range *list {
		(*list)[i].CreateTime = info.CreateTimeDts.Format(utils.TIME_FMT_FULL)
		(*list)[i].ModifyTime = info.ModifyTimeDts.Format(utils.TIME_FMT_FULL)
	}
	return err
}

func (r *Role) Get(c *query.RoleGetReq) error {
	if len(c.Id) == 0 {
		return errors.New("角色ID不能为空")
	}

	id := query.RoleQuery{RoleId: c.Id}
	where := cQuery.MakeCondition(id)
	err := r.Orm.Model(r).Scopes(where).First(r).Error

	if err != nil {
		return err
	}

	r.CreateTime = r.CreateTimeDts.Format(utils.TIME_FMT_FULL)
	r.ModifyTime = r.ModifyTimeDts.Format(utils.TIME_FMT_FULL)

	return nil
}

func (r *Role) Add(data interface{}) (err error) {
	err = r.Orm.Model(&Role{}).Create(data).Error
	return err
}

func (Role) Mod(db *gorm.DB, data interface{}, condition ...func(db *gorm.DB) *gorm.DB) (err error) {
	tx := db.Model(&Role{}).Scopes(condition...).Updates(data)
	if tx.RowsAffected == 0 {
		return errors.New("修改失败")
	}
	return tx.Error
}

func (Role) Del(db *gorm.DB, conds string, params ...interface{}) (err error) {
	tx := db.Model(&Role{}).Where(conds, params...).Delete(&Role{})
	if tx.RowsAffected == 0 {
		return errors.New("修改失败")
	}
	return tx.Error
}
func (Role) FindCountByConds(db *gorm.DB, count *int64, conds string, params ...interface{}) {
	db.Model(&Role{}).Where(conds, params...).Find(&Role{}).Count(count)
	return
}

func (Role) FindListByConds(db *gorm.DB, data interface{}, conds string, params ...interface{}) (err error) {
	db.Model(&Role{}).Where(conds, params...).Find(data)
	return
}

//删除角色管理的菜单
func (Role) DelMenu(db *gorm.DB, conds string, params ...interface{}) (err error) {
	tx := db.Model(&RoleMenu{}).Where(conds, params...).Delete(&RoleMenu{})
	if tx.RowsAffected == 0 {
		return errors.New("删除失败")
	}
	return tx.Error
}

// FindRoleMenuList 查询角色的菜单列表
func (Role) FindRoleMenuList(db *gorm.DB, data interface{}, conds string, params ...interface{}) (err error) {
	db.Model(&RoleMenu{}).Where(conds, params...).Find(data)
	return err
}

// FindUserCount 查询角色关联的用户数量
func (Role) FindUserCount(db *gorm.DB, count *int64, conds string, params ...interface{}) (err error) {
	err = db.Model(&UserRole{}).Where(conds, params...).Find(&UserRole{}).Count(count).Error
	return err
}

func (Role) TableName() string {
	return "sys_role"
}

func (e *Role) Generate() interface{} {
	o := *e
	return &o
}

func (e *Role) GetId() interface{} {
	return e.RoleId
}
